/*******************************************************************************
 * Gadget Utility Functions                        http://binground.codeplex.com
 *                                              Microsoft Public License (Ms-PL)
 * Authors
 *  - Michael Flanakin  2008-09  http://www.michaelflanakin.com
 *
 * util
 *  - animator   : positionally animates images
 *  - busyIcon   : standard busy icon
 *  - codeplex   : functions specific to Codeplex.com
 *  - http       : http functions
 *  - opacity    : opacity-setting functions
 *  - scrolling  : scrolling support
 *  - string     : string functions
 *  - textarea   : functions to support textarea controls
 *  - version    : version functions
 *  - addHandler : adds an event handler
 *
 * gadget
 *  - host       : host properties
 *  - flyout     : flyout show/hide
 *  - properties : property getter/setter
 *  - other      : name, version, init(), load(), dockedInternal, 
 *                 undockedInternal
 ******************************************************************************/

var util = 
{
	/***************************************************************************
	 * util.animator
	 *  - add    : starts animating an image; parameters: <div>, <image url>, 
	 *             <image width>, <full width>, <image height>, <speed in ms>
	 *  - remove : stops animating an image; parameters: <index>
	 **************************************************************************/
	animator:
	{
		objects: [],
		add: function(o, s, x, w, h, speed)
		{
			var o1 = document.createElement("DIV");
			
			with (o1)
			{
				id = o.id + "_animate_0";
				style.width = x + "px";
				style.height = h + "px";
				style.overflow = "hidden";
				
				unselectable = "on";
			   
				var oImg1 = document.createElement("IMG");
				oImg1.id = o.id + "_animate_1";
				oImg1.src = s;
				oImg1.disabled = false;
				oImg1.style.position = "absolute";
				oImg1.style.top = "0px";
				oImg1.style.left = "0px";
				o1.appendChild(oImg1);
			}
			
			o.appendChild(o1);
			
			var n = -1;
			
			for (var i = 0; i < util.animator.objects.length; i++)
			{
				if (util.animator.objects[i] == null)
				{
					util.animator.objects[i] = [o, null];
					n = i;
				}
			}
			
			if (n == -1)
			{
				util.animator.objects.push([o, null]);
				n = util.animator.objects.length - 1;
			}
			
			util.animator.objects[n][1] = setTimeout("util.animator.rotate(" + n + "," + x + "," + w + "," + speed + ")", speed);
			
			return n;
		},
		remove: function(n)
		{
			if (util.animator.objects[n] != null)
			{
				var o = document.getElementById(util.animator.objects[n][0].id + "_animate_0");
				
				if (o)
				{
					o.innerHTML = "";
					
					util.animator.objects[n][0].removeChild(o);
				}
				
				clearTimeout(util.animator.objects[n][1]);
				util.animator.objects[n] = null;
			}
		},
		rotate: function(n, x, w, speed)
		{
			var o = document.getElementById(util.animator.objects[n][0].id + "_animate_1");

			if (o != null) 
			{
				var x0 = parseInt(o.style.left) - x;
				
				if (Math.abs(x0) >= w)
				{
					x0 = 0;
				}
				
				o.style.left = x0 + "px";
				
				util.animator.objects[n][1] = setTimeout("util.animator.rotate(" + n + "," + x + "," + w + "," + speed + ")", speed);
			}
		}
	},
	
	
	/***************************************************************************
	 * util.busyIcon
	 *  - show : displays the busy icon; parameters: <div>
	 *  - hide : hides the busy icon; parameters: <div>
	 **************************************************************************/
	busyIcon:
	{
		show: function(div){div.index = animator.add(div, "images/busyicon.png", 16, 288, 16, 20);},
		hide: function(div){animator.remove(div.index);}
	},
	
	
	
	
	/***************************************************************************
	 * util.http
	 *  - create    : retrieves a new http object instance
	 *  - isSuccess : determines if the http call was successful
	 *  - send      : opens and sends a new web request; params: <get|post>, 
	 *                <url>, <username>, <password>
	 *  - get       : performs an http get; params: <url>, <user>, <password>
	 *  - post      : performs an http post; params: <url>, <user>, <password>
	 **************************************************************************/
	http:
	{
		create: function()
		{
			if (typeof(XMLHttpRequest) != 'undefined')
			{
				return new XMLHttpRequest();
			}
			try
			{
				return new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch(e)
			{
				try
				{
					return new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch(e)
				{}
			}
		},
		isSuccess: function(http){return (http.status==200);},
		send: function(type, url, uid, pwd)
		{
			return util.http.sendAsync(type, url, null, null, uid, pwd);
		},
		sendAsync: function(type, url, success, failed, uid, pwd)
		{
			var isAsync = (success != null);
			var http = util.http.create();
			if (util.string.isEmpty(uid) || util.string.isEmpty(pwd))
			{
				http.open(type, url, isAsync);
			}
			else
			{
				http.open(type, url, isAsync, uid, pwd);
			}
			if (isAsync)
			{
				http.onreadystatechange = function()
				{
					if (http.readyState != 4) { return; }
					if (util.http.isSuccess(http))
					{
						success(http);
					}
					else
					{
						failed(http, http.status);
					}
					http = null;
				};
			}
			http.send();
			if (!isAsync)
			{
				if (util.http.isSuccess(http)) { return http.responseXML; } else { throw(http.status); }
			}
		},
		get:  function(url, uid, pwd) { return util.http.send("get",  url, uid, pwd); },
		post: function(url, uid, pwd) { return util.http.send("post", url, uid, pwd); },
		getAsync:  function(url, success, failed, uid, pwd) { return util.http.sendAsync("get", url, success, failed, uid, pwd); }
	},
	
	
	/***************************************************************************
	 * util.opacity
	 *  - set         : sets opacity; params: <node>, <opacity>
	 *  - lighten     : sets opacity to 25%; params: <node>
	 *  - lightenLess : sets opacity to 50%; params: <node>
	 *  - darken      : sets opacity to 60%; params: <node>
	 *  - darkenMore  : sets opacity to 100%; params: <node>
	 **************************************************************************/
	opacity:
	{
		set         : function(n, o) { if (n==null) { return; } n.style.filter = 'alpha(opacity='+o+')'; },
		lighten     : function(n) { util.opacity.set(n,25); },
		lightenLess : function(n) { util.opacity.set(n,50); },
		darken      : function(n) { util.opacity.set(n,60); },
		darkenMore  : function(n) { util.opacity.set(n,100); }
	},                                                   
	
	
	/***************************************************************************
	 * util.scrolling
	 *  - scroll : scrolls up/down; params: <container id>, <direction/speed>, 
	 *             <continue scrolling flag>
	 *  - start  : starts auto-scrolling; params: <container id>, <dir/speed>
	 *  - stop   : stops auto-scrolling
	 **************************************************************************/
	scrolling:
	{
		//***| properties |*****************************************************
		
		__scrollDirSpeed : 0,

		
		//***| public |*********************************************************
		
		scroll:	function(id, dirSpeed, isLoop)
		{
			// get container
			var ctr = $('#'+id);
			if (ctr == null) { alert("Container to scroll not found"); return; }
			
			// if looping and different direction/speed, stop
			if (isLoop && util.scrolling.__scrollDirSpeed != dirSpeed){return;}
			
			// scroll
			ctr.scrollTop = ctr.scrollTop + (10*dirSpeed);
			
			// loop
			if (isLoop) { setTimeout("util.scrolling.scroll('"+id+"',"+dirSpeed+",true)",150); }
		},
		start: function(id, dirSpeed)
		{
			if(util.scrolling.__scrollDirSpeed != dirSpeed)
			{
				util.scrolling.__scrollDirSpeed = dirSpeed;
				util.scrolling.scroll(id, dirSpeed, true);
			}
		},
		stop: function() { util.scrolling.__scrollDirSpeed = 0; }
	},
	
	
	/***************************************************************************
	 * util.textarea
	 *  - colorAt80 : color to apply to the "chars left" label when at 80%
	 *  - colorAt90 : color to apply to the "chars left" label when at 90%
	 *  - register  : registers a textarea control as a managed control; 
	 *                parameters: <textarea object>, <max length>, <count label>
	 **************************************************************************/
	textarea:
	{
		//***| properties |*****************************************************
		
		colorAt80: '#cc0',
		colorAt90: '#c00',
		
		
		//***| private |********************************************************
		
		__keyPress: function()
		{
			var ta = event.srcElement;
			return (ta.value.length < ta.maxlength*1);
		},
		__keyUp: function()
		{
			var ta = event.srcElement;
			if (ta.value.length > (ta.maxlength*1))
			{
				ta.value = ta.value.substring(0, (ta.maxlength*1));
			}
			if (ta.charsLeftLabel != null)
			{
				var len = ta.value.length;
				ta.charsLeftLabel.innerText   = (ta.maxlength-len);
				if (len > (ta.maxlength*.9))
				{
					ta.charsLeftLabel.style.color = (ta.colorAt90!=null ? ta.colorAt90 : util.textarea.colorAt90);
				}
				else if (len > (ta.maxlength*.8))
				{
					ta.charsLeftLabel.style.color = (ta.colorAt80!=null ? ta.colorAt80 : util.textarea.colorAt80);
				}
				else
				{
					ta.charsLeftLabel.style.color = '';
				}
			}
		},

		
		//***| public |*********************************************************
		
		register: function(ta, max, lbl)
		{
			if (ta==null){alert('No textarea node specified');return;}
			ta.maxlength      = max;
			ta.charsLeftLabel = lbl;
			util.addHandler(ta, "onkeypress", util.textarea.__keyPress);
			util.addHandler(ta, "onkeyup",    util.textarea.__keyUp);
		}
	}
};

var gadget = 
{
	/***************************************************************************
	 * gadget.load() : loads additional gadget settings
	 **************************************************************************/
	load: function()
	{
		// load static sidebar settings
		if (gadget.host.sidebar)
		{
			System.Gadget.settingsUI = gadget.host.settings;
		}
	}
};
